﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Moven
{
	public static class CommonExtensions
	{
		public static bool IsNullOrEmpty(this string str) => string.IsNullOrEmpty(str);
		public static bool IsNullOrEmpty<T>(this IEnumerable<T> sequence) =>
				sequence == null || !sequence.Any();

		public static string ConvertToString(this IEnumerable<char> charSequence) =>
				new string(charSequence.ToArray());

		public static bool IsValidMainlandMobilePhoneNo(this string str) => !str.IsNullOrEmpty() && str.Trim().Length == 11 && Regex.IsMatch(str, @"^((13[0-9])|(15[^4,\D])|(18[0,5-9]))\d{8}$");

		public static IEnumerable<T> ForEach<T>(this IEnumerable<T> sequence, Action<T> action) => ForEach(sequence, (item, _) => action(item));

		public static IEnumerable<T> ForEach<T>(this IEnumerable<T> sequence, Action<T, int> action)
		{
			var index = 0;
			foreach (var item in sequence)
			{
				action(item, index);
				index++;
			}
			return sequence;
		}

		public static IEnumerable<T> Distinct<T>(this IEnumerable<T> sequence, Func<T, T, bool> comparer)
		{
			return sequence.Distinct(new DelegateEqualityComparer<T>(comparer));
		}
	}

	public class DelegateEqualityComparer<T> : IEqualityComparer<T>
	{
		Func<T, T, bool> _comparer;
		public DelegateEqualityComparer(Func<T, T, bool> comparer)
		{
			_comparer = comparer;
		}

		public bool Equals(T x, T y)
		{
			return _comparer(x, y);
		}

		public int GetHashCode(T obj)
		{
#pragma warning disable RECS0017 // Possible compare of value type with 'null'
			if (!typeof(T).IsValueType && obj == null)
#pragma warning restore RECS0017 // Possible compare of value type with 'null'
			{
				return -1;
			}
			return obj.GetHashCode();
		}
	}
}
